home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_068 / mg1b / region.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  7KB  |  287 lines

  1. /*
  2.  *        Region based commands.
  3.  * The routines in this file
  4.  * deal with the region, that magic space
  5.  * between "." and mark. Some functions are
  6.  * commands. Some functions are just for
  7.  * internal use.
  8.  */
  9. #include    "def.h"
  10.  
  11. /*
  12.  * Kill the region. Ask "getregion"
  13.  * to figure out the bounds of the region.
  14.  * Move "." to the start, and kill the characters.
  15.  */
  16. /*ARGSUSED*/
  17. killregion(f, n, k) {
  18.     register int    s;
  19.     REGION        region;
  20.  
  21.     if ((s=getregion(®ion)) != TRUE)
  22.         return (s);
  23.     if ((lastflag&CFKILL) == 0)        /* This is a kill type    */
  24.         kdelete();            /* command, so do magic    */
  25.     thisflag |= CFKILL;            /* kill buffer stuff.    */
  26.     curwp->w_dotp = region.r_linep;
  27.     curwp->w_doto = region.r_offset;
  28.     return (ldelete(region.r_size, KFORW));
  29. }
  30.  
  31. /*
  32.  * Copy all of the characters in the
  33.  * region to the kill buffer. Don't move dot
  34.  * at all. This is a bit like a kill region followed
  35.  * by a yank.
  36.  */
  37. /*ARGSUSED*/
  38. copyregion(f, n, k) {
  39.     register LINE    *linep;
  40.     register int    loffs;
  41.     register int    s;
  42.     REGION        region;
  43.  
  44.     if ((s=getregion(®ion)) != TRUE)
  45.         return (s);
  46.     if ((lastflag&CFKILL) == 0)        /* Kill type command.    */
  47.         kdelete();
  48.     thisflag |= CFKILL;
  49.     linep = region.r_linep;            /* Current line.    */
  50.     loffs = region.r_offset;        /* Current offset.    */
  51.     while (region.r_size--) {
  52.         if (loffs == llength(linep)) {    /* End of line.        */
  53.             if ((s=kinsert('\n', KFORW)) != TRUE)
  54.                 return (s);
  55.             linep = lforw(linep);
  56.             loffs = 0;
  57.         } else {            /* Middle of line.    */
  58.             if ((s=kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
  59.                 return (s);
  60.             ++loffs;
  61.         }
  62.     }
  63.     return (TRUE);
  64. }
  65.  
  66. /*
  67.  * Lower case region. Zap all of the upper
  68.  * case characters in the region to lower case. Use
  69.  * the region code to set the limits. Scan the buffer,
  70.  * doing the changes. Call "lchange" to ensure that
  71.  * redisplay is done in all buffers. 
  72.  */
  73. /*ARGSUSED*/
  74. lowerregion(f, n, k) {
  75.     register LINE    *linep;
  76.     register int    loffs;
  77.     register int    c;
  78.     register int    s;
  79.     REGION        region;
  80.  
  81.     if ((s=getregion(®ion)) != TRUE)
  82.         return (s);
  83.     lchange(WFHARD);
  84.     linep = region.r_linep;
  85.     loffs = region.r_offset;
  86.     while (region.r_size--) {
  87.         if (loffs == llength(linep)) {
  88.             linep = lforw(linep);
  89.             loffs = 0;
  90.         } else {
  91.             c = lgetc(linep, loffs);
  92.             if (ISUPPER(c) != FALSE)
  93.                 lputc(linep, loffs, TOLOWER(c));
  94.             ++loffs;
  95.         }
  96.     }
  97.     return (TRUE);
  98. }
  99.  
  100. /*
  101.  * Upper case region. Zap all of the lower
  102.  * case characters in the region to upper case. Use
  103.  * the region code to set the limits. Scan the buffer,
  104.  * doing the changes. Call "lchange" to ensure that
  105.  * redisplay is done in all buffers. 
  106.  */
  107. /*ARGSUSED*/
  108. upperregion(f, n, k) {
  109.     register LINE    *linep;
  110.     register int    loffs;
  111.     register int    c;
  112.     register int    s;
  113.     REGION        region;
  114.  
  115.     if ((s=getregion(®ion)) != TRUE)
  116.         return (s);
  117.     lchange(WFHARD);
  118.     linep = region.r_linep;
  119.     loffs = region.r_offset;
  120.     while (region.r_size--) {
  121.         if (loffs == llength(linep)) {
  122.             linep = lforw(linep);
  123.             loffs = 0;
  124.         } else {
  125.             c = lgetc(linep, loffs);
  126.             if (ISLOWER(c) != FALSE)
  127.                 lputc(linep, loffs, TOUPPER(c));
  128.             ++loffs;
  129.         }
  130.     }
  131.     return (TRUE);
  132. }
  133.  
  134. /*
  135.  * This routine figures out the bound of the region
  136.  * in the current window, and stores the results into the fields
  137.  * of the REGION structure. Dot and mark are usually close together,
  138.  * but I don't know the order, so I scan outward from dot, in both
  139.  * directions, looking for mark. The size is kept in a long. At the
  140.  * end, after the size is figured out, it is assigned to the size
  141.  * field of the region structure. If this assignment loses any bits,
  142.  * then we print an error. This is "type independent" overflow
  143.  * checking. All of the callers of this routine should be ready to
  144.  * get an ABORT status, because I might add a "if regions is big,
  145.  * ask before clobberring" flag.
  146.  */
  147. getregion(rp) register REGION *rp; {
  148.     register LINE    *flp;
  149.     register LINE    *blp;
  150.     register long    fsize;            /* Long now.        */
  151.     register long    bsize;
  152.  
  153.     if (curwp->w_markp == NULL) {
  154.         ewprintf("No mark set in this window");
  155.         return (FALSE);
  156.     }
  157.     if (curwp->w_dotp == curwp->w_markp) {    /* "r_size" always ok.    */
  158.         rp->r_linep = curwp->w_dotp;
  159.         if (curwp->w_doto < curwp->w_marko) {
  160.             rp->r_offset = curwp->w_doto;
  161.             rp->r_size = (RSIZE) (curwp->w_marko-curwp->w_doto);
  162.         } else {
  163.             rp->r_offset = curwp->w_marko;
  164.             rp->r_size = (RSIZE) (curwp->w_doto-curwp->w_marko);
  165.         }
  166.         return (TRUE);
  167.     }
  168.     blp = curwp->w_dotp;            /* Get region size.    */
  169.     flp = curwp->w_dotp;
  170.     bsize = curwp->w_doto;
  171.     fsize = llength(flp)-curwp->w_doto+1;
  172.     while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  173.         if (flp != curbp->b_linep) {
  174.             flp = lforw(flp);
  175.             if (flp == curwp->w_markp) {
  176.                 rp->r_linep = curwp->w_dotp;
  177.                 rp->r_offset = curwp->w_doto;
  178.                 return (setsize(rp,
  179.                     (RSIZE) (fsize+curwp->w_marko)));
  180.             }
  181.             fsize += llength(flp)+1;
  182.         }
  183.         if (lback(blp) != curbp->b_linep) {
  184.             blp = lback(blp);
  185.             bsize += llength(blp)+1;
  186.             if (blp == curwp->w_markp) {
  187.                 rp->r_linep = blp;
  188.                 rp->r_offset = curwp->w_marko;
  189.                 return (setsize(rp,
  190.                     (RSIZE) (bsize-curwp->w_marko)));
  191.             }
  192.         }
  193.     }
  194.     ewprintf("Bug: lost mark");        /* Gak!            */
  195.     return (FALSE);
  196. }
  197.  
  198. /*
  199.  * Set size, and check for overflow.
  200.  */
  201. setsize(rp, size) register REGION *rp; register RSIZE size; {
  202.  
  203.     rp->r_size = size;
  204.     if (rp->r_size != size) {
  205.         ewprintf("Region is too large");
  206.         return (FALSE);
  207.     }
  208.     return (TRUE);
  209. }
  210.  
  211. #ifdef    PREFIXREGION
  212. /*
  213.  * Implements one of my favorite keyboard macros; put a string at the
  214.  * beginning of a number of lines in a buffer.  The quote string is
  215.  * settable by using set-prefix-string.  Great for quoting mail, which
  216.  * is the real reason I wrote it, but also has uses for creating bar
  217.  * comments (like the one you're reading) in C code.
  218.  */
  219.  
  220. #define PREFIXLENGTH 40
  221. static char prefix_string[PREFIXLENGTH] = { '>', '\0' };
  222.  
  223. /*
  224.  * Prefix the region with whatever is in prefix_string.
  225.  * Leaves dot at the beginning of the line after the end
  226.  * of the region.  If an argument is given, prompts for the
  227.  * line prefix string.
  228.  */
  229.  
  230. /*ARGSUSED*/
  231. prefixregion(f, n, k)
  232. {
  233.     register int    s;
  234.     register LINE    *first, *last;
  235.     register int    nline;
  236.     REGION        region;
  237.     char        *prefix = prefix_string;
  238.  
  239.     if ((f == TRUE) && ((s = setprefix(FALSE, 1, KRANDOM)) != TRUE))
  240.         return (s);
  241.  
  242.     /* get # of lines to affect */
  243.     if ((s = getregion(®ion)) != TRUE)
  244.         return (s);
  245.     first = region.r_linep;
  246.     last = (first == curwp->w_dotp) ? curwp->w_markp : curwp->w_dotp;
  247.     for (nline = 1; first != last; nline++)
  248.         first = lforw(first);
  249.  
  250.     /*move to beginning of region */
  251.     curwp->w_dotp = region.r_linep;
  252.     curwp->w_doto = region.r_offset;
  253.  
  254.     /* for each line, go to beginning and insert the prefix string */
  255.     while (nline--) {
  256.         gotobol();
  257.         for (prefix = prefix_string; *prefix; prefix++)
  258.             (VOID) linsert((RSIZE) 1, *prefix);
  259.         forwline(FALSE, 1, KRANDOM);
  260.     }
  261.     gotobol();
  262.     return (TRUE);
  263. }
  264.  
  265. /*
  266.  * Set prefix string.
  267.  */
  268.  
  269. /*ARGSUSED*/
  270. setprefix(f, n, k)
  271. {
  272.     char        buf[PREFIXLENGTH];
  273.     register int    s;
  274.  
  275.     if (prefix_string[0] == '\0')
  276.         s = ereply("Prefix string: ",buf,sizeof buf);
  277.     else
  278.         s = ereply("Prefix string (default %s): ",
  279.                 buf,sizeof buf,prefix_string);
  280.     if (s == TRUE)
  281.         (VOID) strcpy(prefix_string, buf);
  282.     if ((s == FALSE) && (prefix_string[0] != '\0'))    /* CR -- use old one */
  283.         s = TRUE;
  284.     return (s);
  285. }
  286. #endif
  287.